import { PrismaService } from '@app/prisma';
import { UseGuards } from '@nestjs/common';
import { Args, Int, Mutation, Query, Resolver } from '@nestjs/graphql';
import { GqlAuthPowerGuard, AccountPower } from 'src/auth/auth.guard';
import { StudentService } from './student.service';
import { UserPagination } from '@app/prisma/pagination/user.pagination';
import type { Prisma } from '@prisma/client';
import { ClassesEntity } from '@app/prisma/classes.entity/classes.entity';

@Resolver()
export class StudentResolver {
    constructor(
        private readonly prisma: PrismaService,
        private readonly studentService: StudentService
    ) { }
    @Query(() => UserPagination)
    async searchStudent(
        @Args("skip", { type: () => Int, nullable: true }) skip: number = 0,
        @Args("take", { type: () => Int, nullable: true }) take: number = 20,
        @Args("contains", { nullable: true }) contains?: string,
        @Args("classesId", { type: () => Int, nullable: true }) classesId?: number,
        @Args("scienceId", { type: () => Int, nullable: true }) scienceId?: number,
        @Args("departmentId", { type: () => Int, nullable: true }) departmentId?: number,
        @Args("collegeId", { type: () => Int, nullable: true }) collegeId?: number,
        @Args("name", { nullable: true }) name?: string,
        @Args("account", { nullable: true }) account?: string
    ) {
        const where: Prisma.UserWhereInput = {}
        if (!!name) {
            where.profile = {
                name: {
                    contains: name
                }
            }
        }
        if (!!account) {
            where.account = {
                contains: account
            }
        }
        if (!!collegeId) {
            if (!where.classes) where.classes = {};
            if (!where.classes.science) where.classes.science = {};
            if (!where.classes.science.department) where.classes.science.department = {};
            where.classes.science.department.collegeId = collegeId
        }
        if (!!departmentId) {
            if (!where.classes) where.classes = {};
            if (!where.classes.science) where.classes.science = {};
            where.classes.science.departmentId = departmentId
        }
        if (!!scienceId) {
            if (!where.classes) where.classes = {};
            where.classes.scienceId = scienceId
        }
        if (!!classesId) {
            where.classesId = classesId
        }
        if (!!contains) {
            where.profile = {
                name: {
                    contains
                }
            }
        }
        const total = await this.prisma.user.count({ where })
        const data = await this.prisma.user.findMany({
            where,
            skip,
            take,
            include: {
                profile: true,
                classes: true
            },
            orderBy: {
                id: "desc"
            }
        })
        return {
            total,
            data,
            skip,
            take,
            count: data.length
        }
    }

    @Mutation(() => String)
    @UseGuards(new GqlAuthPowerGuard(AccountPower))
    async uploadStudents(
        @Args("college") college: string,
        @Args("name") name: string,
        @Args("data", { type: () => [[String]] }) data: string[][],
        @Args("department") department: string
    ) {
        const coll = await this.studentService.findOrCreateCollege(college);
        const dept = await this.studentService.findOrCreateDepartmentToCollege(
            coll.id,
            department
        )
        const science = await this.studentService.findOrCreateScience(
            dept.id,
            name
        )
        const classessMap = new Map<string, ClassesEntity>()
        for (let i = 1; i < data.length; i++) {
            const [_, name, account, classess] = data[i];
            if (!name || !classess || !account) continue;
            if (!classessMap.has(classess)) {
                const item = await this.studentService.findOrCreateClasses(
                    science.id,
                    classess
                )
                classessMap.set(item.name, item);
            }
            await this.studentService.findOrCreateUser(
                account,
                name,
                classessMap.get(classess).id
            )
        }
        return "success"
    }
}
